home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 361_01 / enigma.c < prev    next >
C/C++ Source or Header  |  1991-09-18  |  10KB  |  268 lines

  1.  
  2.  
  3. /* Enigma --> A 40/79 version of Louis XIV's "Great Cypher".    15 July 91
  4.  *
  5.  * J.Ekwall
  6.  *
  7.  * Based on "The Bazeries Cylinder" by Rinaldo F. Prisco, BYTE June 83
  8.  * ppg 352-360.
  9.  *
  10.  * Copyrighted to the Public Domain.  Unlimited Distribution Authorized.
  11.  *
  12.  * User Assumes All Risks/Liabilities.
  13.  *
  14.  */
  15.  
  16. #include <ctype.h>
  17. #include <stdek.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21.  
  22. char *BadKey[] = {
  23.     "",
  24.     "Bad Key.  Try Again using these Guidelines:",
  25.     "",
  26.     "   1. Use at least 6 characters (Spaces Don't Count).",
  27.     "   2. Use Mixed Case Text.  (Both Upper & Lower Case).",
  28.     "   3. Include at least One Numberic Digit.",
  29.     "   4. Include at least One Non-AlphaNumeric Character.",
  30.     "   5. Don't Use Control Characters or Extended Characters.",
  31.     "   6. The first 40 (non-Space) characters are Significant.",
  32.     "",
  33.     NULL };
  34.  
  35. char *Cylinder[] = {
  36. "N3@%gGoOWDFYX6ELsinHU7t&10ruzBQ)+?A/#jvy*abdpZ^(-mIK=VqSh9fw$Rk28~_cPe54!JxTlCM",
  37. "oGyLsU47rMNhezY2K9T~^Sufgt%IV&XW*(kvH)-=+qlF!Q6abcBdpACJ13DR@$80?_/#imn5xjZwEOP",
  38. "t)i#AgsY~EIhnuDL@*j(?^mC&Tx8NFbrzoMlaQZ3yB269!UVX$-=vdO41H5wJSqKW0_PRkcp+/fG7%e",
  39. "+?RVO~S/%#yY=higsBzLjEFcwpNPvGqnHekIJQX4bK6dA7rmxuot8f9!l0@DZ2W5$1Ca3^&TM*(U)-_",
  40. "FuOdWfoYnMVZ3v6JQ25CGRezLgKUqAh7r8tlXxB40N9~c!@s$%mk&()-I=Dy_+1iEPS^j?b/#HT*apw",
  41. "oP~!5BO)A-=(bt?xYlnZ3iwGVeyCIqjrXUDdu2L8&9+4/6#Q$%*aF_TgmpNshv7ES^@kHzKMfRJ1c0W",
  42. "rfjqFygiHOR$@v9pd~)4x=CtL_e+IbS8AcUuZ0ksoGPnVlN2!%W1^*D7JwEBKTY3&z5Qm(M-?h/aX6#",
  43. "+HZ6%XRk&?GaSC20#qltzeivjxusDJLTU^cwWE-5/A~hnryBNdIm9*(of!Y3@)pV7$=bQ148F_gPKMO",
  44. "CM6aksIcorNEHUVY157hyf9eilzGSpW80TnL&3*)_bxXjK4$%(+Bd?Z-gA!F/m#t=quP2OQR@vwJ~D^",
  45. "lQfwcgU$nqhR()pAI3rMJ@-ZKT9!=+?v/WjEaF_#emD2dY8^sHLzOVyGb14u6CiPt7~oBxkN5%&0*SX",
  46. "awAClxz5~fU$7^_+&Z8?/%bSqnJvDFeHoWXY239!g@(ci=RdsrNIkyLO0*BmthMTEp46)-#uGKjPQV1",
  47. "sLWoHn24=e+!X^aIM?myJF%AZ*_#36cSl7(UhxRN8pDgfktjuwEOqQVYr59z@0&1)$/bdKTiv~P-BCG",
  48. "sV1H%JI*)t2-lQ5&Gxu=_?zO7^anmryDThRFKZ30P+/X(#ULg!86qvfo4@bENeBCpiMSkjwW9~A$Ycd",
  49. "i)r-=+A?/#EUcK&_O9qgnbtj2N6oxwBGJVRu1aZ@fImLXY~CyPS!$Q%*HvlpFMT3hzWe45s7Dd^k80(",
  50. "fzL&=w_IMHXN$^U*+?/k6#Zg35dsyCFJShBxVolQieamncqvPRObYp27jG0~TA8u@rD1%tKWE94!()-",
  51. "iPSlDr&(4$kzGQubR3jn=o^8T_dX~?/mUC1p#M+wWeHVBc5O0tvIN7hJK6*)-Yg!saAEyqFLZ2f9@%x",
  52. "e08kTgqX7ADfIRU1%_r/GyS4bBnpxCH2htjzP59~6J!c@OQWL$^iwM)-Fm=lsdvaEKNYZV3ou&(+?#*",
  53. "dXcfsTZ-a*=Gz0()3BC_+?/#yEpItnqKNDQFwAPRUW1h2revV56489~mxHLuJibgjoOYlS7!M@$%k^&",
  54. "+!?/pQsEvxbZ9#@e$mDGLqKT0M3IadikyBgRVWjXYh4cfNPSJtnw7%&6*OuAU8~(H)z2F-51=olrC_^",
  55. "INxpUWYE6P90!c&*-F@GQbsST~=1yOVq7+w?/8g5kdHoZJ3v%)R_X2Mj#C^atK$(4LnilfmrzheuABD",
  56. "n!W^8J*7)-UpTM=_t+?/~#lorszdjuxehmwBCvDHKcLORSFXIiqYGf1k25Zb3gayAP4Q690EN@$%&V(",
  57. "fsU^*-=_61nHOb4gqlIC0A~+?k/#SjmFGeDpZctPzwQYWh2789xVdiBN3!$5%MRoXaT&uyL@()EJrvK",
  58. "oxf6h@_G)M+Dl89?/#QPvbKS147L!ukwHX0qjFmaCOdzT3V$%Eit^&*2grI(yc-nN=ZsAJWRe5UpYB~",
  59. "rtRZ3i@Obs$^~Ca)mES48%1W+?oLuvK5=N/U#dxfQyHelMhqFjGcIw6PX7gB90DJV&*(-_nz2p!kATY",
  60. "mVFn7tvIS@~&bueklwxDhLzY5o)pZN!W-EOd4i^=?TsU2KCQR18$%3PyJ90(6_/cA#fHMX*gjB+raqG",
  61. "avAIXY4ijnGOhSTU~0Jdy!@*oWt(-sHK5$L3=?e9NBPpkrcwEbCFDmMzuVZ28)gfR%7^&q_/#6x+Q1l",
  62. "tzQ9~$(-KDuw5FmYhI!_ejG23X4%cgJ+8?/nR#r6)alyAO7dikUPSWLs=Z@CV1&qMTv^p*fN0BxHEob",
  63. "inbz$!%-h=_y*p+x#vZ^j25?Io/Dq1@3CT9ekm46QuX~KGNftFHPwgBrlSJMUWdEaOcVRY70&()8LsA",
  64. "oILdsOVPjD78!yQC9tS~NnFU1g%2^4e56&*cTkAEXpixZW@$v()-=a+MlfzHmGY30bB?/_#qKrJuRhw",
  65. "nRSrOY478%&DiEaIJhqV3Lu9C!g)-^X=mH(z_@+?wk~pFWNZ12cy0$*/#xBTolsdAKMtevbPGQUj56f",
  66. "+fQ(&T=^?/H#voXlS71tzyAbBIkFDnEKMO3wY5mZqj6dJr490acxCheGLgN~sPW2R8U@i!u*)-pV$%_",
  67. "J89~@$w6^t%N3)=n1o!(m+7?jzx_/U#CATPeWbacV&*YfqDK-5Q0gMuEFhivsRLpkyGHlIrdOSXZB24",
  68. "+@?/P5_0HoX#tibqR$FJ^DdfwEKQjkZ1xAWpT4czCGYemg267Su8O9s~!&*(LB)lhnryIMNV%vU3a-=",
  69. "Eh+D?#2RajgP/3kTsQt4d07%p6wJUFBWzcuKCqoMGNVXYZ1mr5SLlbyH8~fIeAO!@9$nxi^&*()-v=_",
  70. "kq_&RnrfcMS1deshbuvzKZGJ36p80%ET2gWw$()O?iVX^o/#alBHjFAIQ!-CN=+tPU4DLmy57~@xY9*",
  71. "w@^K$+NisQjlmISZ1zP238x7%-_MLoE?TbCrGqX9!&hfW(50=VO6J/kg#4d*yDUtRc~puavBA)FenHY",
  72. "acB3FKDGLnMR4jg29@Q&*$d(ty68wmYSzbJOusEWH1!%i^)-=f_+v?CVXqr5/lI#p7~0xehANPTokUZ",
  73. "l25m7~x@%GOBMYg$)-sPUo_EdR*DIZh460!+?/#9t&kyWS(^=vKbfirwLQ8eanjFHTVcpz1CJ3AquXN",
  74. "lX61nh7qf5&=_io3IzTV0W!xta%BeuygsMcDOSZ$*)-HLRFA9kwNQdmrpvGEPY28K~?@+(b/CJU#j^4",
  75. "+?vc/K#NujkoyE6Z2T8tB9s&V)XgPm-riOQ~(L=eIJp7wzYd0nD%CHA1xGq@$a4!Uh^WMFbl35*RSf_",
  76.     NULL };
  77.  
  78. char *Documentation[] = {
  79.     "",
  80.     "Usage:",
  81.     "      Enigma [options] KeyPhrase [file]  --> a Full Ascii Cypher.",
  82.     "",
  83.     "Options:",
  84.     "       /D ---> Decode.",
  85.     "       /H ---> An Historical Note.",
  86.     "       /N ---> Neaten up the output w/ Spaces and LineFeeds.",
  87.     "       /S ---> Silent.  Verbose is Default when Redirected.",
  88.     "",
  89.     " --> NOT APPROVED for Classified Information. <---",
  90.     "",
  91.     "Last Update: 16 July 91/EK",
  92.     NULL};
  93.  
  94. char *History[] = {
  95.     "",
  96.     "   When Louis XIV King of France died in 1715, he left behind",
  97.     "messages coded in \"The Great Cypher\" created for his exclusive",
  98.     "use by mathematician Anotoine Rossignol.",
  99.     "",
  100.     "   For more than a Century, the Great Cypher held off all attacks",
  101.     "until Commander Bazeries of the French Army's \"Black Chamber\"",
  102.     "cracked it, discovering the secret of \"Cylinder Cyphers\".",
  103.     "",
  104.     "   A Century later the British cracked the German Enigma machine",
  105.     "cypher used to encypher Field Orders.  Declassified 30 years later,",
  106.     "the UTRA Secret Project rewrote the History of World War II.",
  107.     "WW II's Enigma was a 7 disk Bazeries Cylinder cypher, much easier to",
  108.     "crack than the 20/26 systems used by diplomats until the middle 50's.",
  109.     "",
  110.     "   This is a 40/79 Cylinder Cypher which will handle the full Ascii",
  111.     "character set include IBM extended characters.  Pencil Pushers",
  112.     "won't crack this one!",
  113.     "",
  114.     NULL };
  115.  
  116. /* Declare Globals */
  117. int DeCode = 0, NeatFlag = 0, Silent = 0;
  118. char HexCode[] = "~!@$%^&*()-=_+?/";
  119. FILE *fp = stdin;
  120.  
  121. /* Declare ProtoTypes */
  122. void Decode(void);
  123. void Encode(void);
  124. void Help(char **dp);
  125. void Swizzle(char *Key);
  126. void Usage(int ReturnCode);
  127.  
  128. main (int argc, char *argv[])
  129. {
  130.     char *tp1;
  131.  
  132.  /* Set Option Flags */
  133.     for (; *argv[1] IS SLASH; argc--, argv++) {
  134.        for (tp1 = argv[1] + 1; *tp1 != NULL; ) {
  135.           switch (toupper(*tp1++)) {
  136.           case  'D': DeCode++;  break;
  137.           case  'H': Help(History);
  138.           case  'N': NeatFlag++; break;
  139.           case  'S': Silent++;  break;
  140.           default:
  141.              fprintf(stderr,"\nInvalid  Option [/%c].\n\n",*tp1); Usage(1);
  142.           }
  143.        }
  144.  
  145.     }
  146.  
  147.  /* Capture Key Word/Phrase */
  148.     if (!OUTFLOW_EXISTS) Silent++;
  149.     if (argc-- < 2) Usage(0); else Swizzle(argv[1]); argv++;
  150.  
  151.  /* Open Specified File (If Any) */
  152.     if (argc > 2) Usage(2);
  153.     if (argc IS 2 && (fp = fopen(argv[1], "r")) IS NULL) {
  154.        perror(argv[1]); Usage(3); }
  155.  
  156.  /* Mainline */
  157.     if (!Silent) fprintf(stderr, "\n"); if (Decode) NeatFlag = 0;
  158.     if (!DeCode) Encode(); else Decode();
  159.     if (!Silent) fprintf(stderr, "\n"); if (NeatFlag) putchar(NL);
  160. }
  161.  
  162. void Decode(void)
  163. {
  164.     int c, i = 0, Flag = 0, Offset, Row = 1;
  165.     char **Disk, *tp1;
  166.  
  167.     for (Disk = Cylinder; (c = fgetc(fp)) != EOF; Disk++) {
  168.  
  169.     /* PreFilter Text */
  170.        if (c IS SPACE || c IS NL) { Disk--; continue; }
  171.        if (*Disk IS NULL) { Disk = Cylinder; Row++; Row %= 40; }
  172.  
  173.     /* Set the Disk to the Letter, Offset by "Row" & Find Value */
  174.        if ((tp1 = strchr(*Disk, c)) IS NULL) exit(1);
  175.        Offset = 74 - Row + (tp1 - *Disk);
  176.        c = ((*Disk)[Offset % 80]);
  177.  
  178.     /* PostProcess Text */
  179.        if (c IS SHARP) c = SPACE;
  180.        else if (isdigit(c));
  181.        else if (isalpha(c));
  182.        else if (Flag) {
  183.           c = 16 * i +  strchr(HexCode, c) - HexCode; Flag--; }
  184.        else { Flag++; i = strchr(HexCode, c) - HexCode; continue; }
  185.        putchar(c); if (!Silent) fprintf(stderr, "%c", c);
  186.     }
  187. }
  188.  
  189. void Encode(void)
  190. {
  191.     int c, n, Flag = 0, Offset, Row = 0, Tally = 0;
  192.     char **Disk;
  193.  
  194.     for (Disk = NULL; (c = fgetc(fp)) != EOF; Disk++) {
  195.  
  196.     /* PreProcess Text */
  197.        if (c IS SPACE) c = SHARP;
  198.